package com.ecoolex.ying.space.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.pojo.Sortings;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.ying.space.core.dao.OutsourcingGoodsDAO;
import com.ecoolex.ying.space.entity.OutsourcingGoods;
import com.ecoolex.ying.space.entity.OutsourcingGoodsExample;
import com.ecoolex.ying.space.entity.OutsourcingGoodsExample.Criteria;
import com.ecoolex.ying.space.entity.OutsourcingGoodsWithBLOBs;
import com.ecoolex.ying.space.entity.OutsourcingGoodsWithBLOBs.Column;
import java.sql.Date;
import java.time.Instant;

import com.ecoolex.ying.space.pojo.QueryMarktingCatalogGoodsDTO;
import com.ecoolex.ying.space.pojo.QueryOutsourcingGoodsAndPackagedDTO;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OutsourcingGoodsManager {
    @Autowired
    private OutsourcingGoodsDAO dao;
    
    @Autowired
    private OutsourcingPackagedGoodsManager outsourcingPackagedGoodsManager;
    
    @Autowired
    private UserWorksShoppingManager userWorksShoppingManager;
    
    @Autowired
    private ShareImageManager shareImageManager;
    
    private void verify(OutsourcingGoods record) {
		BizAssert.isTrue(Check.notNullOrTrimEmpty(record.getName()), ResultCode.VERIFY.build(10), "外购商品名称为空");
		BizAssert.isTrue(Check.notNullAndGteZero(record.getCategoryId()), ResultCode.VERIFY.build(11), "分类id为空");
		BizAssert.isTrue(Check.notNullOrTrimEmpty(record.getCoverImage()), ResultCode.VERIFY.build(12), "列表图片为空");
		BizAssert.isTrue(Check.notNullOrTrimEmpty(record.getImages()), ResultCode.VERIFY.build(13), "商品图片为空");
		BizAssert.isTrue(Check.notNullAndGteZero(record.getRetailPrice()), ResultCode.VERIFY.build(14), "零售价格为空");
		BizAssert.isTrue(Check.notNullOrTrimEmpty(record.getBuyLink()), ResultCode.VERIFY.build(15), "购买链接为空");
	}
    
    public OutsourcingGoodsWithBLOBs add(OutsourcingGoodsWithBLOBs record , String createUser) {
    	verify(record);
    	
    	record.setOnline(false);
    	record.setDeleted(OutsourcingGoods.NOT_DELETED);
		record.setCreateUser(createUser);
		record.setCreateTime(Date.from(Instant.now()));
		record.setUpdateUser(createUser);
		record.setUpdateTime(Date.from(Instant.now()));

		dao.insert(record);
		
		// 添加分享图片
        shareImageManager.addShareImage(record.getCoverImage());
        
		return record;
    }
    
    public OutsourcingGoodsWithBLOBs edit(OutsourcingGoodsWithBLOBs record , String updateUser) {
    	verify(record);
    	record.setUpdateUser(updateUser);
    	record.setUpdateTime(Date.from(Instant.now()));
    	
    	dao.updateByPrimaryKeySelective(record, Column.excludes(Column.online,Column.deleted,Column.createUser,Column.createTime));
    	
    	// 添加分享图片
        shareImageManager.addShareImage(record.getCoverImage());
    	return record;
    }
    
    public void delete(OutsourcingGoodsWithBLOBs record , String updateUser) {
    	//检查外购套餐中是否使用了这个商品
    	boolean flag = outsourcingPackagedGoodsManager.getByOutsourcingGoodsId(record.getOutsourcingGoodsId());
    	BizAssert.isTrue(flag,ResultCode.VERIFY.build(16), "有套餐使用了该商品");
    	//检查作品购物标签是否使用了这个商品
    	boolean flag2 = userWorksShoppingManager.getByOutsourcingGoodsId(record.getOutsourcingGoodsId());
    	BizAssert.isTrue(flag2,ResultCode.VERIFY.build(17), "有作品购物标签使用了该商品");
    	record.setDeleted(OutsourcingGoods.IS_DELETED);
    	record.setUpdateUser(updateUser);
    	record.setUpdateTime(Date.from(Instant.now()));
    	dao.updateByPrimaryKeySelective(record, Column.deleted,Column.updateUser,Column.updateTime);
    }
    
    public void onlineGoods(OutsourcingGoodsWithBLOBs record,String updateUser) {
    	record.setOnline(true);
    	record.setUpdateUser(updateUser);
    	record.setUpdateTime(Date.from(Instant.now()));
    	dao.updateByPrimaryKeySelective(record, Column.online,Column.updateUser,Column.updateTime);
    }
    
    public void offlineGoods(OutsourcingGoodsWithBLOBs record,String updateUser) {    	
    	record.setOnline(false);
    	record.setUpdateUser(updateUser);
    	record.setUpdateTime(Date.from(Instant.now()));
    	dao.updateByPrimaryKeySelective(record, Column.online,Column.updateUser,Column.updateTime);
    }
    
    public boolean canOffline(Integer outsourcingGoodsId) {
    	OutsourcingGoodsExample example = new OutsourcingGoodsExample();
    	Criteria criteria = example.createCriteria();
    	criteria.andOutsourcingGoodsIdEqualTo(outsourcingGoodsId).andOnlineEqualTo(true).andDeletedEqualTo(OutsourcingGoods.NOT_DELETED);
    	OutsourcingGoods outsourcingGoods = dao.selectOneByExample(example);
    	if(Check.notNull(outsourcingGoods)) {
    		return outsourcingPackagedGoodsManager.getByOutsourcingGoodsId(outsourcingGoodsId);
    	}
    	return false;
    }
    
    public OutsourcingGoodsWithBLOBs getById(Integer outsourcingGoodsId) {
    	return dao.selectByPrimaryKeyWithLogicalDelete(outsourcingGoodsId, OutsourcingGoods.NOT_DELETED);
    }
    
    public OutsourcingGoods getOnlineById(Integer outsourcingGoodsId) {
    	OutsourcingGoodsExample example = new OutsourcingGoodsExample();
    	Criteria criteria = example.createCriteria();
    	criteria.andOutsourcingGoodsIdEqualTo(outsourcingGoodsId);
    	criteria.andOnlineEqualTo(true);
    	criteria.andDeletedEqualTo(OutsourcingGoods.NOT_DELETED);
    	
    	return dao.selectOneByExample(example);
    }
    
    public Pagination<OutsourcingGoodsWithBLOBs> query(String name,Boolean online, Sorting[] sorts, Page page){
    	OutsourcingGoodsExample example = new OutsourcingGoodsExample();
    	Criteria criteria = example.createCriteria();
    	if(Check.notNullOrTrimEmpty(name)) {
    		criteria.andNameLike('%' + name
			+ '%');
    	}
    	if(Check.notNull(online)) {
    		criteria.andOnlineEqualTo(online);
    	}
    	criteria.andDeletedEqualTo(OutsourcingGoods.NOT_DELETED);
		example.orderBy(Sortings.builder(sorts).verify(Column::valueOf).toSql());
		example.setOffset(page.getFirstIndex());
		example.setRows(page.getPageSize());

		return Pagination.create(page, dao.countByExample(example), () -> dao.selectByExampleWithBLOBs(example));
    }
    
    public OutsourcingGoodsWithBLOBs getByIdForH5(Integer outsourcingGoodsId) {
    	OutsourcingGoodsExample example = new OutsourcingGoodsExample();
    	Criteria criteria = example.createCriteria();
    	criteria.andOutsourcingGoodsIdEqualTo(outsourcingGoodsId);
    	criteria.andOnlineEqualTo(true);
    	criteria.andDeletedEqualTo(OutsourcingGoods.NOT_DELETED);
    	
    	return dao.selectOneByExampleWithBLOBs(example);
    }
    
    public Pagination<OutsourcingGoodsWithBLOBs> queryForH5(Integer categoryId,String name, Sorting[] sorts,
			Page page){
    	OutsourcingGoodsExample example = new OutsourcingGoodsExample();
    	Criteria criteria = example.createCriteria();
    	if(Check.notNullAndNeqZero(categoryId)) {
    		criteria.andCategoryIdEqualTo(categoryId);
    	}
    	if(Check.notNullOrTrimEmpty(name)) {
    		criteria.andNameLike("%"+name+"%");
    	}
    	criteria.andDeletedEqualTo(OutsourcingGoods.NOT_DELETED);
    	criteria.andOnlineEqualTo(true);
		example.orderBy(Sortings.builder(sorts).verify(Column::valueOf).toSql());
		example.setOffset(page.getFirstIndex());
		example.setRows(page.getPageSize());

		return Pagination.create(page, dao.countByExample(example), () -> dao.selectByExampleWithBLOBs(example));
    }

	public Pagination<OutsourcingGoodsWithBLOBs> queryUnrelatedWithCatalogGoods(QueryMarktingCatalogGoodsDTO query, Sorting[] sorts, Page page) {
		long count = dao.countUnrelatedWithCatalog(query.getCatalogId(), query.getName());
		return Pagination.create(page, count, () -> dao.queryUnrelatedWithCatalog(query.getCatalogId(), query.getName(), Sortings.builder(sorts).toSql(), page));
	}
	
	public Pagination<QueryOutsourcingGoodsAndPackagedDTO> queryOutsourcingGoodsAndPackaged(String name,Page page){
		return Pagination.create(page, 
			dao.countGoodsAndPackaged(name),
			()-> dao.queryGoodsAndPackaged(name, page));
	}
}